/*
 ------------------------------------------------------------------------------
 Copyright (C) 2013 Eternal Games.

 This file is part of the GLQuake source code.

 The GLQuake source code is free software; you can redistribute it and/or
 modify it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2 of the License, or (at your
 option) any later version.

 The GLQuake source code is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 more details.

 You should have received a copy of the GNU General Public License along with
 the GLQuake source code; if not, write to the Free Software Foundation, Inc.,
 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 ------------------------------------------------------------------------------
*/


//
// collision.h - public header to all other files
//


#ifndef __FRAMEWORK_COLLISION_H__
#define __FRAMEWORK_COLLISION_H__


/*
 ==============================================================================

 Collision Detection:

 ==============================================================================
*/

#define MAX_TRACE_DISTANCE			(MAX_WORLD_SIZE * 2.0f)

#define BOX_EPSILON					1.0f		// Should always be larger than clip epsilon

// Content masks
#define	MASK_ALL					(-7)
#define	MASK_SOLID					(CONTENT_SOLID)
#define	MASK_LIQUID					(CONTENT_WATER | CONTENT_ACID | CONTENT_LAVA)

typedef struct clipModel_t			clipModel_t;
typedef struct clipLeaf_t			clipLeaf_t;

struct contactInfo_t {
	glqPlane				plane;				// Surface plane at impact, only valid if allInside == false
};

struct trace_t {
	bool					allInside;			// If true, the start and end points were inside a clip volume
	bool					startInside;		// If true, the start point was inside a clip volume

	float					fraction;			// Fraction of trace completed, 1.0 == didn't hit anything
	glqVec3					direction;			// Normalized trace direction

	glqVec3					point;				// Final position

	contactInfo_t			c;					// Contact information, only valid if fraction < 1.0
};

// Functions exported by the engine
struct glqCollision_t {
	// Loads and prepares the given map for collision detection
	void					(*LoadMap)(const char *name);

	// Loads and registers the given model
	clipModel_t *			(*RegisterModel)(const char *name);

	// Gets the bounds of the given model
	void					(*GetModelBounds)(clipModel_t *model, glqBounds &bounds);

	// Sets up a box model for collision detection
	clipModel_t *			(*SetupBoxModel)(int contents, const glqBounds &bounds);

	// Returns the entity string for the given map
	char *					(*EntityString)();

	//
	byte *					(*LeafPVS) (clipLeaf_t *leaf);

	//
	bool					(*PointInLeaf) (const glqVec3 &point, int *nodeNum);

	// Performs a point (bounds == 0) or box (bounds != 0) trace through the
	// map or a model.
	// A trace with start == end will actually perform a position test.
	void					(*Trace)(const glqVec3 &start, const glqVec3 &end, const glqBounds &bounds, int contentMask, clipModel_t *model, const glqVec3 &modelOrigin, const glqMat3 &modelAxis, trace_t *trace);

};


#endif	// __FRAMEWORK_COLLISION_H__